package models

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/go-redis/redis/v8"
	"gopkg.in/ini.v1"
	"os"
	"time"
)

var ctx = context.Background() // 创建一个空的上下文对象
var rdbClient *redis.Client
var redisEnable bool

func init() {
	// 读取app.ini的配置信息
	config, iniErr := ini.Load("./conf/app.ini")
	if iniErr != nil {
		fmt.Printf("fail to read file %v", iniErr)
		os.Exit(1)
	}
	// 读取相关信息
	ip := config.Section("redis").Key("ip").String()
	port := config.Section("redis").Key("port").String()
	redisEnable, _ = config.Section("redis").Key("redisEnable").Bool()
	if redisEnable { // 判断redis是否开启
		rdbClient = redis.NewClient(&redis.Options{ // 新建redis客户端对象
			Addr:     ip + ":" + port,
			Password: "",
			DB:       0,
		})
		_, err := rdbClient.Ping(ctx).Result() // 测试链接
		if err != nil {
			fmt.Println("redis数据库链接失败:", err)
			os.Exit(1)
		}
	}
}

type CacheDb struct{}

// 对redis进行二次封装
func (c CacheDb) Set(key string, value interface{}, expiration int) {
	if redisEnable {
		v, err := json.Marshal(value) // value是一个空接口类型, 可以是任意类型, 使用json.Marshal转成字节切片
		if err == nil {
			rdbClient.Set(ctx, key, string(v), time.Duration(expiration)*time.Second)
		}
	}
}

func (c CacheDb) Get(key string, value interface{}) bool { // 这里的value需要外部传入指
	if redisEnable {
		valurStr, err1 := rdbClient.Get(ctx, key).Result()
		if err1 == nil && valurStr != "" {
			err2 := json.Unmarshal([]byte(valurStr), value)
			if err2 != nil {
				return false
			}
			return true
		}
	}
	return false
}

func (c CacheDb) FlushAll() {
	if redisEnable {
		rdbClient.FlushAll(ctx)
	}
}

var CacheDB = &CacheDb{} // 暴露对象地址, 供外部调用
